﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Prism.Commands;
using Prism.Events;
using System.Windows.Input;
using System.Windows;
using Prism.Mvvm;
using SoonCode.Core;
using SoonCode.FocusTest.Events;
using SoonCode.FocusTest.Models;
using SoonCode.FocusTest.Utils;
using ImTools;
using System.Windows.Threading;
using static NPOI.HSSF.Util.HSSFColor;

namespace SoonCode.FocusTest.ViewModels
{
    internal class TestItemFViewModel : BindableBase
    {
        private int TestItemIndex = 6;
        private string testType = "itemF";
        private RandomHelper randomHelper = new RandomHelper(0, 10);
        private int tabIndex = 0;
        private int err = 0;
        private TestInfo testInfo;
        private IEventAggregator aggregator;
        private int level = 1;
        private int matrix = 2;
        private SubscriptionToken answerToken;
        private List<ObservableCollection<FItemHelper>> questionList;
        private DispatcherTimer timer;
        private int cutedown = 5;
        private EventInfo questEventInfo = new EventInfo();
        string[] levelRule = ["2:2", "3:3", "3:4", "4:5", "4:6", "5:7", "6:7", "6:8", "6:9", "6:10", "7:11"];
        private string helpSoundText = "停止播放提示语";
        private bool helpIsPlay = true;
        private int member_age = 0;
        public string HelpSoundText
        {
            get { return helpSoundText; }
            set
            {
                helpSoundText = value;
                RaisePropertyChanged();
            }
        }


        public int Cutedown
        {
            get { return cutedown; }
            set
            {
                cutedown = value;
                RaisePropertyChanged();
            }
        }

        public int Matrix
        {
            get { return matrix; }
            set
            {
                matrix = value;
                RaisePropertyChanged();
            }
        }

        public int Level
        {
            get { return level; }
            set
            {
                level = value;
                RaisePropertyChanged();
            }
        }

        private ObservableCollection<FItemHelper> itemList;

        public ObservableCollection<FItemHelper> ItemList
        {
            get { return itemList; }
            set
            {
                itemList = value;
                RaisePropertyChanged();
            }
        }

        public TestItemFViewModel(IEventAggregator aggregator)
        {
            this.aggregator = aggregator;
            AnswerRightCommand = new DelegateCommand(AnswerRightHandler);
            AnswerErrorCommand = new DelegateCommand(AnswerErrorHandler);
            questEventInfo.Type = testType;
            timer = new DispatcherTimer();
            timer.Tick += Timer_Tick;
            timer.Interval = TimeSpan.FromSeconds(1);
            aggregator.GetEvent<EndTestEvent>().Subscribe(() =>
            {
                timer.Stop();
                aggregator.GetEvent<StudentAnswerEvent>().Unsubscribe(answerToken);
            });
            aggregator.GetEvent<TestLoadEvent>().Subscribe(OnLoaded);
        }

        private void Timer_Tick(object? sender, EventArgs e)
        {
            if (Cutedown == 1)
            {
                SoundPlayer.PlayDing();
                timer.Stop();
                foreach (FItemHelper helper in ItemList)
                {
                    helper.color = "White";
                    helper.img = helper.img+"1";
                }
            }

            Cutedown--;
            questEventInfo.Data["cutedown"] = Cutedown;
            this.aggregator.GetEvent<QuestionChangeEvent>().Publish(questEventInfo);
        }

        private void OnLoaded(int p)
        {
            if (p != this.TestItemIndex - 1)
            {
                if (answerToken != null)
                    aggregator.GetEvent<StudentAnswerEvent>().Unsubscribe(answerToken);
                return;
            }

            this.testInfo = GlobalModel.Instance.TestInfo;
            member_age=GlobalModel.Instance.MemberInfo.age;
            TabIndex = 0;
            Task.Run(GenerateList);
            Level = 1;
            Matrix = 2;
            answerToken = aggregator.GetEvent<StudentAnswerEvent>().Subscribe(SutdentAnswer);
            SoundPlayer.Play("1000:item6.mp3");
        }

        private void SutdentAnswer(EventInfo payload)
        {
            if (payload == null || payload.Type != testType)
            {
                return;
            }

            if (payload.Data.ContainsKey("submit"))
            {
                foreach (FItemHelper helper in ItemList)
                {
                    if ((helper.check && helper.color != "Black") || ((!helper.check) && helper.color == "Black"))
                    {
                        AnswerErrorHandler();
                        return;
                    }
                }

                AnswerRightHandler();
                return;
            }

            int index = Convert.ToInt16(payload.Data["index"]);
            ItemList[index].bindColor= ItemList[index].color = ItemList[index].color == "Black" ? "White" : "Black";
        }

        public int TabIndex
        {
            get { return tabIndex; }
            set
            {
                tabIndex = value;
                RaisePropertyChanged();
            }
        }
        public ICommand HelpCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    if (helpIsPlay)
                    {
                        SoundPlayer.Stop();
                        HelpSoundText = "播放提示语";
                        helpIsPlay = false;
                    }
                    else
                    {
                        SoundPlayer.Play("item6.mp3");
                        HelpSoundText = "停止播放提示语";
                        helpIsPlay = true;
                    }
                });
            }
        }
        public ICommand SkipCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    SoundPlayer.Stop();
                    this.aggregator.GetEvent<ChangeTestEvent>().Publish(TestItemIndex);
                });
            }
        }

        public ICommand StartCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    SoundPlayer.Stop();
                    TabIndex = 1;
                    Test();
                });
            }
        }

        public ICommand AnswerRightCommand { get; set; }
        public ICommand AnswerErrorCommand { get; set; }

        private void AnswerErrorHandler()
        {
            err++;
            if (err >= 2)
            {
                complete();
                return;
            }

            Test();
        }


        private void AnswerRightHandler()
        {
            err = 0;
            Level++;
            Test();
        }

        private void complete()
        {
            var ele = Keyboard.FocusedElement;
            Keyboard.Focus(null);
            DialogUtil.Show(aggregator, $"通过关数=（{Level - 1}）关，本项结束，进入下一项");
            Keyboard.Focus(ele);
            testInfo.data[TestItemIndex].item_score = (int)((double)(Level - 1) / questionList.Count * 100) + "";
            this.aggregator.GetEvent<ChangeTestEvent>().Publish(TestItemIndex);
        }

        private async void GenerateList()
        {
            questionList = new List<ObservableCollection<FItemHelper>>();
            for (int lv = 0; lv < levelRule.Length; lv++)
            {
                string[] l = levelRule[lv].Split(":");
                int all = l[0].ToInt();
                ObservableCollection<FItemHelper> items = new ObservableCollection<FItemHelper>();
                for (int i = 0; i < all * all; i++)
                {
                    FItemHelper item = new FItemHelper(this.member_age);
                    item.index = i;
                    items.Add(item);
                }

                questionList.Add(items);
            }

            ItemList = questionList[0];
        }

        private async void Test()
        {
            if (Level > questionList.Count)
            {
                complete();
                return;
            }

            Cutedown = 5;
            questEventInfo.Data["cutedown"] = Cutedown;
            ItemList = questionList[Level - 1];
            string[] level = levelRule[Level - 1].Split(":");
            int all = level[0].ToInt();
            int black = level[1].ToInt();
            randomHelper = new RandomHelper(0, all * all, "-");
            string[] numbers = randomHelper.next(black).Split("-");
            RandomHelper imgRandom= new RandomHelper(1,11, ",");
            string[] imgs= imgRandom.next(black).Split(",");
            string imgSux= member_age >=5 ? "" : "t";
            int i = 0;
            foreach (FItemHelper helper in ItemList)
            {
                helper.check = numbers.Contains(helper.index.ToString());
                helper.bindColor=helper.color = helper.check ? "Black" : "White";
                if (this.member_age < 5)
                    helper.bindColor = "White";
                
                helper.img= helper.check?$"pack://application:,,,/Images/e{imgSux}{imgs[i++]}.png":"";
            }

            this.aggregator.GetEvent<QuestionChangeEvent>().Publish(questEventInfo);
            EventInfo info = new EventInfo() { Type = testType };
            Matrix = (int)Math.Sqrt(ItemList.Count);
            info.Data["helper"] = ItemList;
            this.aggregator.GetEvent<LevelUpdateEvent>().Publish(info);
            timer.Start();
        }
    }

    public class FItemHelper : BindableBase
    {
        private string _color;
        private string _img;
        private string _bindColor;
        private int age;
        public FItemHelper(int age)
        {
            this.age= age;
        }
        public string img
        {
            get { return _img; }
            set
            {
                _img = value;
                RaisePropertyChanged();
            }
        }

        public string color
        {
            get { return _color; }
            set
            {
                _color = value;
                RaisePropertyChanged();
            }
        }
        public string bindColor
        {
            get { return _bindColor; }
            set
            {
                _bindColor = value;
                RaisePropertyChanged();
            }
        }

        public int index { get; set; }
        public bool check { get; set; }
    }
}